package com.concurrent.coline.part6.future;

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * 类说明：演示Future等的使用
 */
public class UseFuture {

    /*实现Callable接口，允许有返回值*/
    private static class UseCallable implements Callable<Integer> {

        private int sum;

        @Override
        public Integer call() throws Exception {
            System.out.println("Callable子线程开始计算");
            Thread.sleep(2000);
            for (int i = 0; i < 5000; i++) {
                sum = sum + i;
            }
            System.out.println("Callable子线程计算完成，结果=" + sum);
            return sum;
        }

    }

    private static class UseRunnable implements Runnable {
        private int sum;

        @Override
        public void run() {
            System.out.println("UseRunnable子线程开始计算");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for (int i = 0; i < 5000; i++) {
                sum = sum + i;
            }
        }
    }

    public static void main(String[] args)
            throws InterruptedException, ExecutionException {

        UseCallable useCallable = new UseCallable();
        FutureTask<Integer> futureTask = new FutureTask<>(useCallable);
        new Thread(futureTask).start();
        Random r = new Random();
        //随机决定是获得结果还是终止任务
        if (r.nextBoolean()) {
            System.out.println("Get UseCallable result = " + futureTask.get());
        } else {
            System.out.printf("中断计算 flag: %s \n", futureTask.cancel(true));
        }

        /*
          个人理解使用runnable初始化FutureTask目的是为了并发执行线程的同时保证后续的业务执行顺序
         */
        UseRunnable useRunnable = new UseRunnable();
        FutureTask<Integer> runnableFutureTask = new FutureTask(useRunnable, 1);
        new Thread(runnableFutureTask).start();
        System.out.println("runnableFutureTask get " + runnableFutureTask.get());

        System.out.println("main ended");

    }

}
